/**
 * Alipay.com Inc. Copyright (c) 2004-2010 All Rights Reserved.
 */
package org.mobile.model.util;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author John Lee
 * @version $Id: SysUtil.java,v 1.11 2012/01/10 12:10:21 chenc Exp $
 */
public class SysUtil {

    private static final Logger LOG = LoggerFactory
            .getLogger(SysUtil.class);

    private static final SimpleDateFormat FORMAT = new SimpleDateFormat(
            "yyyyMMdd00");
    private static final SimpleDateFormat FORMAT_VIEW = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm");
    private static final SimpleDateFormat FORMAT_DATE = new SimpleDateFormat(
            "yyyyMMddHHmm");
    private static final SimpleDateFormat FORMAT_DATE_1 = new SimpleDateFormat(
            "yyyyMMdd");
    private static final SimpleDateFormat sdf1 = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    private static final SimpleDateFormat FORMAT_TIME = new SimpleDateFormat(
            "HH:mm");

    private static final Pattern PHONE_PATTERN = Pattern
            .compile("1(3|4|5|8)\\d{9}");

    /**
     * @param str
     * @return
     */
    public static boolean sqlInject(String str) {
        if(str == null || str.trim().equals("")) {
            return false;
        }

        String injectStr = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";

        String injectStrArray[] = injectStr.split("\\|");
        for(int i = 0; i < injectStrArray.length; i++) {
            if(str.indexOf(injectStrArray[i]) >= 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取一个随机字符串。
     * @param length
     *            随机字符串的长度
     * @param model
     *            0 数字 1 字母 2 数字加字母
     * @return 一个随机字符串
     */
    public static String getRandomString(int length, int model) {
        if(length < 1) {
            return "";
        }

        if(model < 0 || model > 2) {
            model = 0;
        }

        StringBuffer sb = new StringBuffer(length);

        for(int i = 0; i < length; i++) {
            if(model == 0) {
                sb.append(genRandomDigit(i != 0));
            } else if(model == 1) {
                sb.append(genRandomLetter());
            } else if(model == 2) {
                sb.append(genRandomChar(i != 0));
            }

        }

        return sb.toString();
    }

    /**
     * 获取一个随机字符（允许数字0-9和小写字母）。
     * @return 一个随机字符
     */
    private static char genRandomChar(boolean allowZero) {
        int randomNumber = 0;
        do {
            Random r = new Random();
            randomNumber = r.nextInt(36);
        } while((randomNumber == 0) && !allowZero);

        if(randomNumber < 10) {
            return (char) (randomNumber + '0');
        } else {
            return (char) (randomNumber - 10 + 'a');
        }
    }

    public static boolean isCheck1(String str) {
        if(str.equals("0")) {
            return true;
        }
        return false;
    }

    public static boolean isCheck2(String str) {
        if(str.equals("3")) {
            return true;
        }
        return false;
    }

    public static boolean isBlank(String s) {
        if(s == null || s.equals(""))
            return true;

        else
            return false;
    }

    private static char genRandomLetter() {
        int randomNumber = 0;
        Random r = new Random();
        randomNumber = r.nextInt(26);
        return (char) (randomNumber + 'a');
    }

    /**
     * 获取一个随机字符（只允许数字0-9）。
     * @return 一个随机字符
     */
    private static char genRandomDigit(boolean allowZero) {
        int randomNumber = 0;

        do {
            Random r = new Random();
            randomNumber = r.nextInt(10);
        } while((randomNumber == 0) && !allowZero);

        return (char) (randomNumber + '0');
    }

    /**
     * 去除html标签
     * @param HTMLStr
     * @return
     */
    public static String removeHtmlTag(String HTMLStr) {
        if(StringUtils.isBlank(HTMLStr)) {
            return "";
        }

        String htmlStr = HTMLStr;
        String textStr = "";
        java.util.regex.Pattern p_script;
        java.util.regex.Matcher m_script;
        java.util.regex.Pattern p_style;
        java.util.regex.Matcher m_style;
        java.util.regex.Pattern p_html;
        java.util.regex.Matcher m_html;
        try {
            String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
            String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
            String regEx_html = "<[^>]+>";
            p_script = Pattern.compile(regEx_script,
                    Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll("");
            p_style = Pattern.compile(regEx_style,
                    Pattern.CASE_INSENSITIVE);
            m_style = p_style.matcher(htmlStr);
            htmlStr = m_style.replaceAll("");
            p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
            m_html = p_html.matcher(htmlStr);
            htmlStr = m_html.replaceAll("");
            textStr = htmlStr.replaceAll(" ", "");
            // textStr = htmlStr.replaceAll("<", "<");
            // textStr = htmlStr.replaceAll(">", ">");
            // textStr = htmlStr.replaceAll("®", "®");
            // textStr = htmlStr.replaceAll("&", "&");
            textStr = StringUtils.replace(textStr, "&nbsp;", "");
            textStr = StringUtils.replace(textStr, "\r", "");
            textStr = StringUtils.replace(textStr, "\n", "");
            textStr = StringUtils.trim(textStr);

        } catch(Exception e) {
            System.err.println("Html2Text: " + e.getMessage());
        }
        return textStr;
    }

    public static String UTF8TOGBK(String str) {
        try {
            return new String(str.getBytes("utf-8"), "GBK");
        } catch(UnsupportedEncodingException e) {
            LOG.error("utf8 到 GBK 转码失败", e);
        }
        return str;
    }

    public static String GBKTOUTF8(String str) {
        try {
            return new String(str.getBytes("gbk"), "utf-8");
        } catch(UnsupportedEncodingException e) {
            LOG.error("GBK到 utf8 转码失败", e);
        }
        return str;
    }

    public static String ISOToUTF8(String str) {
        try {
            if(StringUtils.isEmpty(str))
                return str;
            return new String(str.getBytes("ISO-8859-1"), "utf-8");
        } catch(UnsupportedEncodingException e) {
            LOG.error("iso-8859-1到 utf8 转码失败", e);
        }
        return str;
    }

    public static String parseRole(Integer userRole) {
        switch(userRole) {
        case 1:
            return "系统管理员";
        case 2:
            return "销售人员";
        case 3:
            return "导游";
        case 4:
            return "业务员";
        default:
            break;
        }
        return "";
    }

    /**
     * 获得给定时间的零点
     * @param date
     * @return
     */
    public static String getDateStart(Date date) {
        return FORMAT.format(date);
    }

    /**
     * 获得给定时间n天后的零点
     * @param date
     * @param n
     * @return
     */
    public static String getDateStart(Date date, int n) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(Calendar.DAY_OF_MONTH, n);
        return FORMAT.format(gc.getTime());
    }

    public static String datetoformtter(String s) {
        String formmatterdate = "";
        if(s.length() >= 12) {
            String year = s.substring(0, 4) + "-";
            String month = s.substring(4, 6) + "-";
            String day = s.substring(6, 8) + "/";
            String minite = s.substring(8, 10) + ":";
            String second = s.substring(10, 12);
            formmatterdate = year + month + day + minite + second;
        }
        return formmatterdate;
    }

    public static String stringBuilder(String... strings) {
        StringBuilder sb = new StringBuilder();
        if(strings != null && strings.length > 0) {
            for(String s : strings)
                sb.append(s);
        }
        return sb.toString();
    }

    /**
     * @param date
     *            yyyyMMddHHmm
     * @return
     */
    public static String dateStore(Date date) {
        if(date == null)
            return "";
        return FORMAT_DATE.format(date);
    }

    public static String dateView(Date date) {
        if(date == null)
            return "";
        return FORMAT_VIEW.format(date);
    }

    public static String dateViews(Date date) {
        if(date == null)
            return "";
        return sdf1.format(date);
    }

    /**
     * @param date
     *            yyyyMMddHHmm
     * @return
     */
    public static String dateView(String date) {
        if(StringUtils.isEmpty(date))
            return "";
        try {
            return FORMAT_VIEW.format(FORMAT_DATE.parse(date));
        } catch(ParseException e) {
        }
        return "";
    }

    public static String dateTime(String date) {
        if(StringUtils.isEmpty(date))
            return "";
        try {
            return FORMAT_TIME.format(FORMAT_DATE.parse(date));
        } catch(ParseException e) {
        }
        return "";
    }

    public static String dateView1(String date) {
        if(StringUtils.isEmpty(date))
            return "";
        try {
            return FORMAT_VIEW.format(FORMAT_DATE_1.parse(date));
        } catch(ParseException e) {
        }
        return "";
    }

    public static String msgTypeToShowName(String msgType) {
        try {
            int mt = Integer.parseInt(msgType);
            switch(mt) {
            case 1:
                return "短信发送";
            case 2:
                return "满意度调查";
            case 3:
                return "业务宣传";
            case 4:
                return "导游发送";
            }
        } catch(Exception e) {
        }
        return "";
    }

    public static boolean isPhoneNumber(String phoneNumber) {
        Matcher matcher = PHONE_PATTERN.matcher(phoneNumber);
        return matcher.matches();
    }

    /**
     * get user type
     * @param userType
     * @return 2 normal user, 1 doctor, null is unvalid
     */
    public static String getUserType(String userType) {
        if(userType != null) {
            if(userType.equals("1") || userType.equals("2"))
                return "1";
            else if(userType.equals("0") || userType.equals("3")
                    || userType.equals("4") || "5".equals(userType))
                return "2";
        }
        return null;
    }

    public static String getClientType(String clientType) {
        String client = "";
        if("0".equals(clientType)) {
            client = "android大众版";
        } else if("1".equals(clientType)) {
            client = "android医生版";
        } else if("2".equals(clientType)) {
            client = "ios医生版";
        } else if("3".equals(clientType)) {
            client = "ios大众版";
        } else if("4".equals(clientType)) {
            client = "win8大众版";
        } else if("5".equals(clientType)) {
            client = "winPhone大众版";
        }
        return client;
    }

    public boolean getRegStatus(String r) {
        boolean regStatus = false;
        if("5".equals(r)) {
            regStatus = true;
        }
        return regStatus;
    }

    public String getStatus(String r) {
        String regStatus = "异常";
        if("5".equals(r)) {
            regStatus = "正常";
        }
        return regStatus;
    }

    public String getBankCode(Integer b) {
        String bank = "";
        if(b == 1) {
            bank = "工行";
        } else if(b == 2) {
            bank = "支付宝";
        } else if(b == 9) {
            bank = "先诊疗后付费";
        }
        return bank;
    }

    public String getAnnounceStatus(String status) {
        String t = "已发送";
        if("0".equals(status)) {
            t = "等待发送";
        } else if("2".equals(status)) {
            t = "发送失败";
        }
        return t;
    }

    /**
     * 根据身份证号获取性别
     * @param idCard
     * @return 1 男 2 女
     */
    public static String getGenderByIdCard(String idCard) {
        if(idCard.length() == CHINA_ID_MIN_LENGTH) {
            idCard = conver15CardTo18(idCard);
        }
        String sCardNum = idCard.substring(16, 17);
        if(Integer.parseInt(sCardNum) % 2 != 0) {
            return "1";
        }
        return "2";
    }

    /**
     * 将15位身份证号码转换为18位
     * @param idCard
     *            15位身份编码
     * @return 18位身份编码
     */
    public static String conver15CardTo18(String idCard) {
        String idCard18 = "";
        if(idCard.length() != CHINA_ID_MIN_LENGTH) {
            return null;
        }
        if(isNum(idCard)) {
            // 获取出生年月日
            String birthday = idCard.substring(6, 12);
            Date birthDate = null;
            try {
                birthDate = new SimpleDateFormat("yyMMdd").parse(birthday);
            } catch(ParseException e) {
                e.printStackTrace();
            }
            Calendar cal = Calendar.getInstance();
            if(birthDate != null)
                cal.setTime(birthDate);
            // 获取出生年(完全表现形式,如：2010)
            String sYear = String.valueOf(cal.get(Calendar.YEAR));
            idCard18 = idCard.substring(0, 6) + sYear
                    + idCard.substring(8);
            // 转换字符数组
            char[] cArr = idCard18.toCharArray();
            if(cArr != null) {
                int[] iCard = converCharToInt(cArr);
                int iSum17 = getPowerSum(iCard);
                // 获取校验位
                String sVal = getCheckCode18(iSum17);
                if(sVal.length() > 0) {
                    idCard18 += sVal;
                } else {
                    return null;
                }
            }
        } else {
            return null;
        }
        return idCard18;
    }

    /**
     * 将power和值与11取模获得余数进行校验码判断.
     * @param iSum .
     * @return 校验位
     */
    public static String getCheckCode18(int iSum) {
        String sCode = "";
        switch(iSum % 11) {
        case 10:
            sCode = "2";
            break;
        case 9:
            sCode = "3";
            break;
        case 8:
            sCode = "4";
            break;
        case 7:
            sCode = "5";
            break;
        case 6:
            sCode = "6";
            break;
        case 5:
            sCode = "7";
            break;
        case 4:
            sCode = "8";
            break;
        case 3:
            sCode = "9";
            break;
        case 2:
            sCode = "x";
            break;
        case 1:
            sCode = "0";
            break;
        case 0:
            sCode = "1";
            break;
        default:
            break;
        }
        return sCode;
    }

    /**
     * 将身份证的每位和对应位的加权因子相乘之后，再得到和值.
     * @param iArr 数组
     * @return 身份证编码。
     */
    public static int getPowerSum(int[] iArr) {
        int iSum = 0;
        if(power.length == iArr.length) {
            for(int i = 0; i < iArr.length; i++) {
                for(int j = 0; j < power.length; j++) {
                    if(i == j) {
                        iSum = iSum + iArr[i] * power[j];
                    }
                }
            }
        }
        return iSum;
    }

    /**
     * 将字符数组转换成数字数组.
     * @param ca
     *            字符数组
     * @return 数字数组
     */
    public static int[] converCharToInt(char[] ca) {
        int len = ca.length;
        int[] iArr = new int[len];
        try {
            for(int i = 0; i < len; i++) {
                iArr[i] = Integer.parseInt(String.valueOf(ca[i]));
            }
        } catch(NumberFormatException e) {
            LOG.error("", e);
        }
        return iArr;
    }

    /**
     * 数字验证
     * @param val
     * @return 提取的数字。
     */
    public static boolean isNum(String val) {
        return val == null || "".equals(val) ? false : val
                .matches("^[0-9]*$");
    }

    /** 中国公民身份证号码最小长度。 */
    public static final int CHINA_ID_MIN_LENGTH = 15;

    /** 每位加权因子 */
    public static final int power[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7,
            9, 10, 5, 8, 4, 2 };

    /**
     * 获取访问者真实ip
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0
                || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0
                || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0
                || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
